Table of Contents |
Windows NT and Windows 95 both let you administer the registry from remote locations. A simple way to change values on a system is to use Regedt32.exe to connect to a remote computer and modify the registry. This procedure works fine for small numbers of modifications or queries, but what if you have 20, 50, or 100 workstations to change?
You may decide that you want a way to automatically perform registry administration tasks on a remote computer. REGREM is a utility written in C that demonstrates remote registry administration; it queries the registry of a remote Windows NT computer. The program prints to the screen a copy of the network configuration settings for a remote Windows NT computer.
// regrem.c // Steve Scoggins 1997 #include <stdio.h> #include <time.h> #include <conio.h> #include <ctype.h> #include <windows.h> #define OK ERROR_SUCCESS main(int argc, char *argv[]) { static char lpszNIC_Description[80]; static char lpszNIC_Manufacturer[80]; static char lpszNIC_ProductName[80]; static char lpszNIC_ServiceName[80]; static char lpszTcpip_DefaultGateway[20]; static char lpszTcpip_IPAddress[20]; static char lpszTcpip_SubnetMask[20]; static char lpszTcpip_Domain[80]; static char lpszTcpip_Hostname[80]; static char lpszTcpip_NameServer[80]; static char lpszTcpip_SearchList[128]; static char lpszComputerName[80]; static char lpszDefaultDomainName[80]; char szKeyPart1[] = "SYSTEM\\CurrentControlSet\\Services\\"; char szKeyPart2[] = "\\Parameters"; char szServiceKey[128]; long InterruptNumber, IoBaseAddress; HKEY hkey, hNetKey ; DWORD lenKeyValue; unsigned long DataType; int err; char *name = argv[1]; if ((err = RegConnectRegistry(name, HKEY_LOCAL_MACHINE, &hkey)) == OK) { // Open the Registry Key for the first instance of a Network Adapter // in the Registry // Read the Description, Manufacturer, Product Name, and Service Name // for this instance of an installed Network Adapter. if(RegOpenKey(hkey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ NetworkCards\\1",&hNetKey) == ERROR_SUCCESS) { RegQueryValueEx(hNetKey, "Description", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "Description", 0, &DataType,(LPTSTR) lpszNIC_Description, &lenKeyValue); printf("Windows NT Network Adapter:\n"); printf("Description: %s\n",lpszNIC_Description); RegQueryValueEx(hNetKey, "Manufacturer", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "Manufacturer", 0, &DataType, (LPTSTR)lpszNIC_Manufacturer, &lenKeyValue); printf("Manufacturer: %s\n",lpszNIC_Manufacturer); RegQueryValueEx(hNetKey, "ProductName", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "ProductName", 0, &DataType, (LPTSTR)lpszNIC_ProductName, &lenKeyValue); printf("Product Name: %s\n",lpszNIC_ProductName); RegQueryValueEx(hNetKey, "ServiceName", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "ServiceName", 0, &DataType, (LPTSTR)lpszNIC_ServiceName, &lenKeyValue); printf("Service Name: %s\n",lpszNIC_ServiceName); RegCloseKey(hNetKey); } // Now that we have the ServiceName for the Network Adapter from the // NetworkCards key we will reconstruct the correct ServiceKey path // based on the Service Name for this network adapter. strcpy(szServiceKey, szKeyPart1); strcat(szServiceKey, lpszNIC_ServiceName); strcat(szServiceKey, szKeyPart2); if(RegOpenKey(hkey, (LPCTSTR) szServiceKey, &hNetKey) == ERROR_SUCCESS) { RegQueryValueEx(hNetKey, "InterruptNumber", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "InterruptNumber", 0, &DataType, (LPBYTE) &InterruptNumber, &lenKeyValue); printf("Interrupt Number: %x\n",InterruptNumber); RegQueryValueEx(hNetKey, "IoBaseAddress", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "IoBaseAddress", 0, &DataType, (LPBYTE) &IoBaseAddress, &lenKeyValue); printf("IO Base Address: %x\n",IoBaseAddress); RegCloseKey(hNetKey); } // Open the TCP/IP Key for this Network Adapter // Read some of the key TCP/IP parameters for this Network Adapter strcat(szServiceKey, "\\Tcpip"); if(RegOpenKey(hkey, (LPCTSTR) szServiceKey ,&hNetKey) == ERROR_SUCCESS) { RegQueryValueEx(hNetKey, "DefaultGateway", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "DefaultGateway", 0, &DataType,(LPTSTR) lpszTcpip_DefaultGateway, &lenKeyValue); printf("TCP/IP DefaultGateway : %s\n",lpszTcpip_DefaultGateway); RegQueryValueEx(hNetKey, "IPAddress", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "IPAddress", 0, &DataType, (LPTSTR)lpszTcpip_IPAddress, &lenKeyValue); printf("TCP/IP IPAddress : %s\n",lpszTcpip_IPAddress); RegQueryValueEx(hNetKey, "SubnetMask", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "SubnetMask", 0, &DataType, (LPTSTR)lpszTcpip_SubnetMask, &lenKeyValue); printf("TCP/IP Subnet Mask : %s\n",lpszTcpip_SubnetMask); RegCloseKey(hNetKey); } // Read the global TCP/IP paramters if(RegOpenKey(hkey, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\ Parameters",&hNetKey) == ERROR_SUCCESS) { RegQueryValueEx(hNetKey, "Domain", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "Domain", 0, &DataType, (LPTSTR)lpszTcpip_Domain, &lenKeyValue); printf("TCP/IP Domain Name: %s\n",lpszTcpip_Domain); RegQueryValueEx(hNetKey, "Hostname", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "Hostname", 0, &DataType, (LPTSTR)lpszTcpip_Hostname, &lenKeyValue); printf("TCP/IP Hostname: %s\n",lpszTcpip_Hostname); RegQueryValueEx(hNetKey, "NameServer", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "NameServer", 0, &DataType, (LPTSTR)lpszTcpip_NameServer, &lenKeyValue); printf("TCP/IP DNS Name Servers: %s\n",lpszTcpip_NameServer); RegQueryValueEx(hNetKey, "SearchList", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "SearchList", 0, &DataType, (LPTSTR)lpszTcpip_SearchList, &lenKeyValue); printf("TCP/IP Domain Name Search List: %s\n",lpszTcpip_SearchList); RegCloseKey(hNetKey); } // Read the Computer Name and Domain Name for this Windows NT Computer if(RegOpenKey(hkey, "SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ ActiveComputerName", &hNetKey) == ERROR_SUCCESS) { RegQueryValueEx(hNetKey, "ComputerName", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "ComputerName", 0, &DataType, (LPTSTR)lpszComputerName, &lenKeyValue); printf("Windows NT Computer Name: %s\n",lpszComputerName); RegCloseKey(hNetKey); } if(RegOpenKey(hkey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ Winlogon", &hNetKey) == ERROR_SUCCESS) { RegQueryValueEx(hNetKey, "DefaultDomainName", 0, &DataType, NULL, &lenKeyValue); RegQueryValueEx(hNetKey, "DefaultDomainName", 0, &DataType, (LPTSTR)lpszDefaultDomainName, &lenKeyValue); printf("Windows NT DomainName: %s\n",lpszDefaultDomainName); RegCloseKey(hNetKey); } RegCloseKey(hkey); } else { switch (err) { #define MSG(x) case x : printf("%s\t\t\t\n", #x) MSG(ERROR_OPERATION_ABORTED); break; MSG(ERROR_BAD_NETPATH); break; MSG(ERROR_ACCESS_DENIED); break; default: printf("Error #%u (look in WINERROR.H)\n", err); break; } printf("failed to connect to remote registry"); } printf("bye!\n"); return 0; }
The source and the compiled executable are available on the CD-ROM that comes with this book. To run REGREM, you must be logged on as an administrator of the Windows NT Domain for the remote computer.
A network administrator could use this type of software utility to query the network configuration for all the Windows NT computers on the local network. The results are printed to the screen. If you want a file containing this information, you can redirect the screen printout to a file using the following form of the command:
REGREM ComputerName > FileName
Sample output from REGREM is shown below.
Windows NT Network Adapter: Description: 3Com Etherlink III PCI Bus-Master Adapter (3C590) Manufacturer: 3Com Product Name: El59x Service Name: El59x1 Interrupt Number: 12ff8c IO Base Address: 3 TCP/IP DefaultGateway : 200.200.200.254 TCP/IP IPAddress : 200.200.200.200 TCP/IP Subnet Mask : 255.255.255.0 TCP/IP Domain Name: test.com TCP/IP Hostname: bigdog TCP/IP DNS Name Servers: TCP/IP Domain Name Search List: Windows NT Computer Name: BIGDOG Windows NT DomainName: BIGDOG bye!
You can also run the Regrem.exe client on any Windows 95 or Windows NT workstation that is logged on to your Windows NT Domain. To run this utility on a Windows 95 computer, install the Microsoft Remote Registry Services. The REGREM client utility uses Winreg.dll as an RPC client that communicates with the RPC server on the remote Windows NT computer. The RPC service on the remote computer uses Regserv.exe.
You must enable user-level access before you can run remote registry software on a Windows 95 computer. You also must be authenticated by the Windows NT Domain server before you are allowed to connect to a remote registry on a Windows NT computer in the Windows NT Domain.
Note: for remote registry administration to work, you must enable remote registration on the remote Windows 95 computers.
This program is meant as a demonstration of what is possible. Make sure you visit this books Web site frequently for updates and other programming examples.
Another way to modify the Windows NT registry automatically without writing code is to use .inf files. You can change multiple workstations and servers remotely and automatically. To avoid having to fire up Regedt32.exe for each change, you can simply tell the Logon.bat file to run your .inf file, which can perform any sort command or registry modification.
The following command line runs an .inf file on a Windows NT computer:
RUNDLL32 syssetup,SetupInfObjectInstallAction DefaultInstall 128 E:\NT Registry\cdautoff.inf
It is very important that you provide the fully qualified path to the .inf file. If you just supply the filename, this procedure will not work. You can place this command line in a logon batch file if you want to make this modification for multiple users. You can then edit the users profiles and specify this batch file.
Listed below is an INF file that turns off CD-ROM Autorun via the registry.
; CDAUTOFF.INF ; ; This is an example INF setup information file to turn OFF CD-ROM Autorun [Version] Signature="$Windows NT$" Provider=%Provider% [Strings] Provider="Steve Scoggins" [DefaultInstall] AddReg = add.reg [add.reg] HKLM,SYSTEM\CurrentControlSet\Services\Cdrom,"Autorun",0x10001,0
You can automatically roll out any number of modifications to the registry using this technique. The trick is learning what the bit fields for each key does.
For more information about using INF files to automate installing applications or making registry changes, I recommend the references cited below:
Table of Contents |